import java.util.ArrayList;

import midi.IntervalOperations;
import midi.MidiController;
import midi.MidiPhrase;
import midi.IntervalOperations.interval;
import midi.patterns.MyPatterns;


import processing.core.*;
import scales.MidiPhraser;
import codeanticode.gsvideo.*;

/**
 * Processing Applet which demonstrates grabbing colors from a webcam
 * and passing them to midi output.
 * 
 * @author Dylan James
 *
 */
public class WebCamColorMidi extends PApplet{
	GSCapture cam; // Capture object
	int vidX = 320, vidY = 240; // Size of the applet window and capture
	int redVal, greenVal, blueVal; // Variables to hold the value of each color
	int colorVal, totalVal; // Hold the total color value
	PFont font; // Font to write on the screen with
	MidiController midiController;
	MidiPhraser happyPhraser;
	MidiPhraser happyHarmPhraser;
	MidiPhraser sadPhraser;
	MidiPhrase happyPhrase;
	MidiPhrase happyHarmPhrase;
	MidiPhrase sadPhrase;
	int noteNumber;
	
	ArrayList<MidiPhrase> midiPhrases;

	
	public void setup() {
		// Initialize the applet window
		size(vidX, vidY);
		background(0);
		fill(255);
		stroke(255);
		
		// Load and set the font
		font = loadFont("CourierNew36.vlw");
		textFont(font, 32);
		
		frameRate(30);
		
		// Initialize the capture device
		cam = new GSCapture(this, vidX, vidY);
		
		midiController = new MidiController();
		happyPhraser = new MidiPhraser(MyPatterns.Pattern1.getIntervals(),
				MyPatterns.Pattern1.getVelocities(), MyPatterns.Pattern1.getLengths(),
				60);
		
		happyHarmPhraser = new MidiPhraser(MyPatterns.Pattern1.getIntervals(),
				MyPatterns.Pattern1.getVelocities(), MyPatterns.Pattern1.getLengths(),
				IntervalOperations.raise(60, interval.PerfectFifth));
		
		sadPhraser = new MidiPhraser(MyPatterns.Pattern2.getIntervals(),
				MyPatterns.Pattern2.getVelocities(), MyPatterns.Pattern2.getLengths(),
				60);
		
		new Thread(midiController).start();
		
		midiPhrases = new ArrayList<MidiPhrase>();
	}

	public void draw(){
		// Grab image from the webcam if possible
		if (cam.available() == true){
			cam.read();
		}
		// Store it
		image(cam, 0, 0);
		// Get the color from the current mouse position
		colorVal = get(mouseX, mouseY);
		
		// Store each color individual
		redVal = (int) red(colorVal);
		greenVal = (int) green(colorVal);
		blueVal = (int) blue(colorVal);
		totalVal = (redVal + greenVal + blueVal) / 3;
		
		fill(0, 0);
		// Draw a circle by the cursor
		ellipse(mouseX, mouseY, 10, 10);
		
		
		fill (255, 255);
		
		// Draw each color to the applet
		text("R = " + redVal, 5, 30);
		text("G = " + greenVal, 5, 60);
		text("B = " + blueVal, 5, 90);
		text("T = " + totalVal, 5, 120);
		
		updateNoteNumber(redVal);
		
		midiController.setBPM(greenVal);
		
		if (totalVal > 90){
			happyPhraser.setRootNoteNumber(noteNumber);
			happyPhrase = happyPhraser.toMidiPhrase();
			happyHarmPhraser.setRootNoteNumber(IntervalOperations.raise(noteNumber, interval.PerfectFifth));
			happyHarmPhrase = happyHarmPhraser.toMidiPhrase();
			
			midiPhrases.clear();
			midiPhrases.add(happyPhrase);
			midiPhrases.add(happyHarmPhrase);
			midiController.setPhrases(midiPhrases);
		}
		else
		{
			sadPhraser.setRootNoteNumber(noteNumber);
			sadPhrase = sadPhraser.toMidiPhrase();
			midiController.setPhrase(sadPhrase);
		}
	}
	
	private void updateNoteNumber(int val){
		noteNumber = 60 + (int)(12 * ((val / 64) - 2));
	}

	// Allows the program to be run as a java application.
	public static void main(String args[]){
		PApplet.main(new String[] { "--present", "WebCamColorMidi"});
	}
}
